/**
 * 
 */
package cs342.project1.mathNotebook.gui;

import javax.swing.table.AbstractTableModel;

import cs342.project1.mathNotebook.PKI.*;
import cs342.project1.mathNotebook.db.DatabaseObjectNotFoundException;
import cs342.project1.mathNotebook.db.*;
import cs342.project1.mathNotebook.db.DBNotebook;
import cs342.project1.mathNotebook.db.DatabaseContext;
import cs342.project1.mathNotebook.db.DatabaseException;

/**
 * @author philip
 *
 */
public class PermissionsTableModel extends AbstractTableModel {
	protected DBPerson[] people;
	protected DBNotebook notebook;
	protected byte[] desKey;
	/**
	 * @throws DatabaseException
	 * 
	 */
	public PermissionsTableModel(DBPerson[] people, DBNotebook notebook, byte[] desKey) {
		//get notebooks
		this.people = people;
		this.notebook = notebook;
		this.desKey = desKey;
	}

	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getColumnCount()
	 */
	@Override
	public int getColumnCount() {
		return 3;
	}
	
	@Override
	public String getColumnName(int col) {
		switch(col) {
		case 0:
			return "Username";
		case 1:
			return "Read";
		case 2:
			return "Write";
		}
		return "";
	}
	
	@Override
	public Class<?> getColumnClass(int col) {
		switch(col) {
		case 0:
			return String.class;
		case 1:
			return Boolean.class;
		case 2:
			return Boolean.class;
		}
		return Object.class;
	}
	

	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getRowCount()
	 */
	@Override
	public int getRowCount() {
		return people.length;
	}

	/* (non-Javadoc)
	 * @see javax.swing.table.TableModel#getValueAt(int, int)
	 */
	@Override
	public Object getValueAt(int row, int col) {
		DBPerson personForRow = people[row];
		switch(col) {
		case 0:
			try {
				return personForRow.getUsername();
			} catch (DatabaseException e) {
				return null;
			}
		case 1:
			try{
				return new Boolean(notebook.getKeyForReader(personForRow) != null);
			} catch(DatabaseObjectNotFoundException  e){
				return new Boolean(false);
			}
		case 2:
			try {
				return new Boolean(notebook.hasWriter(personForRow));
			} catch (DatabaseException e) {
				return new Boolean(false);
			}
		}
		return null;
	}
	
	@Override
	public boolean isCellEditable(int row, int col) {
		if(col == 0)
		return false;
		else return true;
	}
	@Override
	public void setValueAt(Object value, int row, int col) {
       DBPerson personForRow = people[row];
       boolean val = ((Boolean)value).booleanValue();
		switch(col) {
		case 1:
			try{
				if(val){
				
					byte[] publicKeyBytes = personForRow.getPublicKey();
					System.out.println(String.format("%s's num pub key bytes %d", personForRow.getUsername(), publicKeyBytes.length));
					SimpleRSAPublicKey pub = new SimpleRSAPublicKey(publicKeyBytes);
					byte[] encryptedDesKey = pub.encrypt(desKey);
					notebook.addReader(personForRow,encryptedDesKey);
					
					
					
				}
				else{
					if(!notebook.getOwner().getUsername().equals(personForRow.getUsername())){
						notebook.removeReader(personForRow);
						notebook.removeWriter(personForRow);
						
					}
				}
				
			} catch(DatabaseException  e){
				
			}
			break;
		case 2:
			try {
				if(val){
					if(!notebook.hasReader(personForRow)){
						SimpleRSAPublicKey pub = new SimpleRSAPublicKey(personForRow.getPublicKey());
						byte[] encryptedDesKey = pub.encrypt(desKey);	
						notebook.addReader(personForRow,encryptedDesKey);
					}
					
					notebook.addWriter(personForRow);
					fireTableDataChanged();
				}
				else{
					if(!notebook.getOwner().getUsername().equals(personForRow.getUsername()));
					notebook.removeWriter(personForRow);				
				}
				
			} catch (DatabaseException e) {
				
			}
		}
		fireTableDataChanged();
    }
	

}
